/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;

import org.apache.log4j.Logger;

import who.tmap.bo.BaseMap;
import who.tmap.bo.cd.CDTypes;
import who.tmap.common.TMapException;
import who.tmap.toolkit.EditMode;
import who.tmap.toolkit.MappingToolKit;
import who.tmap.toolkit.impl.AttrHelper;
import who.tmap.toolkit.impl.MappingToolKitFactory;
import who.tmap.toolkit.impl.MappingToolKitScalingHelper;
import who.tmap.toolkit.shape.MapShape;
import who.tmap.toolkit.shape.PolygonShape;
import who.tmap.ui.cd.JFrameCartographicDisplay;
import who.tmap.ui.cd.point.JPanelCDPoint;
import who.tmap.ui.undo.UndoAction;
import who.tmap.ui.undo.UndoActions;
import who.tmap.ui.undo.UndoManager;
import who.tmap.ui.undo.impl.UndoManagerImpl;
import who.tmap.ui.util.DataTableDataModel;
import who.tmap.ui.util.MiscUIHelper;
import who.tmap.ui.util.ThematicMapPropertiesUIHelper;
import who.tmap.util.MiscHelper;

/**
 * A Frame to display the map (base map as well as thematic map)
 * 
 * @author stl
 */
public class JFrameMap extends JInternalFrame {

    private static Logger logger = Logger.getLogger(JFrameMap.class);  
   
    private static UndoManager undoManager =UndoManagerImpl.getInstance();
    
    private JFrameMap thisFrame =this;
    // Should do something loosely coupled instead of this
    private JFrameCartographicDisplay jFrameCartographicDisplay =null;
    private JFrameData jFrameData =null;

    private BaseMap baseMap =null;
	private MappingToolKit mtk =null;
	private UserMouseInputListener mil =null;
	private UserKeyListener kl =null;
	private MiscHelper miscHelper =new MiscHelper();
	private MiscUIHelper miscUIHelper =new MiscUIHelper(); 
	private boolean geoBoxNotInitializedAlreadyWarned;
	
	private JToolBar jToolBar = null;
	
	private JToolBar.Separator jSeparatorCommon;	
	private JToggleButton jButtonSelect = null;
	private JToggleButton jButtonLine = null;
	private JToggleButton jButtonImage = null;	
	private JButton jButtonDelete = null;
	private JToolBar.Separator jSeparatorBaseMap;

	private JToggleButton jButtonPolygon = null;
	private JButton jButtonClosePolygon = null;
	private JToggleButton jButtonFill = null;
	private JToggleButton jButtonMultiSelect = null;
	private JButton jButtonPalette = null;
	private JToggleButton jButtonText = null;
	private JButton jButtonFitToWindow = null;
	private JButton jButtonGeographicBox = null;
	private JButton jButtonMergePolygon = null;
	private JToggleButton jButtonInsertPolygonPoint = null;	
	private JToggleButton jButtonDeletePolygonPoint = null;
	private JButton jButtonSelectByPolygonName = null;
	private JToggleButton jButtonUseExistingBoundaries = null;	
	private JButton jButtonBaseMapLineWidth =null;
	
	private JPanel jPanel = null;
	private JToolBar jToolBarZoom = null;  
	private JLabel jLabelZoom = null;
	private JScrollPane jScrollPane = null;
	
	private JPanel jMainPanel = null;

	private JToggleButton jButtonSplitPolygon = null;
	private JCheckBox jCheckBoxMap = null;
	private JCheckBox jCheckBoxCD = null;
	private JCheckBox jCheckBoxAnnotations = null;
	
	private JToolBar.Separator jSeparatorAnnotations;
	private JToggleButton jButtonEllipse = null;
	private JToggleButton jButtonRectangle = null;
	private JToggleButton jButtonCross = null;
	private JToggleButton jButtonTriangle = null;
	private JButton jButtonBackgroundImage = null;
	private JToggleButton jButtonLabelList = null;
	private JButton jButtonAddMargins = null;
	private JButton jButtonHelp = null;
	private JToggleButton jButtonDisputedBorder = null;
	private JLabel jLabelCoords = null;
	private JToggleButton jToggleButtonZoomIn = null;
	
	private JToolBar.Separator jSeparatorCartographicDisplay;
	private JToggleButton jButtonPointEntry = null;
	private JToggleButton jButtonPointEntryWithoutDesc = null;	
	private JButton jButtonSelectByCDPointDesc = null;
	private JToggleButton jToggleButtonZoomOut = null;
	private JLabel jLabelZoomInfo = null;
	// Acquisition button, from a digitizer
	private JToolBar.Separator jSeparatorDigitizer;
	private JToggleButton jToggleButtonDigitizerWithoutDesc =null;
	private JToggleButton jToggleButtonDigitizer =null;	
	
	private JButton jButtonUndo =null;
	private JButton jButtonRedo =null;	

	/**
	 * This is the default constructor
	 */
	public JFrameMap() {
		super( "Base Map", 
			  true, //resizable
			  true, //closable
			  true, //maximizable
			  true);//iconifiable
			  
		initialize();
	}
	
	public void setFrameCartographicDisplay( JFrameCartographicDisplay jFrameCartographicDisplay ) {
		this.jFrameCartographicDisplay =jFrameCartographicDisplay;
		mil.setJPanelCDPoint( jFrameCartographicDisplay.getJPanelCDPoint() );		
	}
	
	public void setFrameData( JFrameData jFrameData ) {
		this.jFrameData =jFrameData;
		mil.setDataTableModel( jFrameData.getJTable().getModel() );
	}
	
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		setSize(483, 200);
		setOpaque( true );
		
		try {
			mtk =MappingToolKitFactory.getInstance().getGraphicToolKit();
		} catch (TMapException e2) {
			e2.printStackTrace();
		}
		
		setContentPane( getJMainPanel() );
		
		mtk.setContainer( getJPanel() );	
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	
		setClosable( false );
		
		//TODO instanciates another way
		mil =new UserMouseInputListenerImpl();
		mil.setContainer( getJScrollPane() );
		mil.setMtk( mtk );
		mil.setJButtonPolygon( getJButtonPolygon() );
		mil.setJButtonSelect( getJButtonSelect() );
		mil.setJLabelCoords( getJLabelCoords() );
		mil.setJLabelZoomInfo( getJLabelZoomInfo() );

		getJPanel().addMouseListener( mil );
		getJPanel().addMouseMotionListener( mil );

		setFocusable( true );
		
		kl =new UserKeyListenerImpl();
		kl.setContainer( this );
		kl.setMtk( mtk );
		kl.setMil( mil );
		getJPanel().addKeyListener( kl ); 
		
		setFrameIcon( miscHelper.getImageIcon("ic_map2.gif") );
		this.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				thisFrame.fitToWindow();
				JFrameMap.logger.debug("Window has been resized");
			}
		});
		this.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				kl.keyTyped(e);
			}
		});
		this.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				getJPanel().requestFocusInWindow();
			}
		});
		
		undoManager.setMtk( mtk );
						
	}
	
	public UserMouseInputListener getMil() {
		return mil;
	}
	
	public void apply() {
		jFrameCartographicDisplay.apply();
	}
	
	class BaseMapJPanel extends JPanel {
		
	    protected void paintComponent( Graphics g ) {
	    	
	    	if ( mtk.isRepaintNeeded() ) {
		        super.paintComponent( g );
		        
		        Graphics myg =g;
		        
		        mtk.paintThematicMap( (Graphics2D)g );
				logger.debug("Inside BaseMapJPanel.paintComponent" );
	
				g =myg;
				
				// for key management
				requestFocusInWindow();
	    	}
	    }
	}
	
	public void clickPolygonButton() {
	    getJButtonPolygon().doClick();
	}
	
	private void clickSelectButton() {
		getJButtonSelect().doClick();
	}

	public void setEditMode( int editMode ) {
    	mil.setEditMode( editMode );
    	
		setCommonButtonsVisible( false );

    	if ( ( editMode & EditMode.BASE_MAP ) == EditMode.BASE_MAP ) {   
    		setCommonButtonsVisible( true );       		
    		setBaseMapButtonsVisible( true );
    	} else {
    		setBaseMapButtonsVisible( false );
    		clickSelectButton();
    	}

    	if ( ( editMode & EditMode.ANNOTATIONS ) == EditMode.ANNOTATIONS ) {
    		setCommonButtonsVisible( true );    		
    		setAnnotationsButtonsVisible( true );    		
    	} else {
    		setAnnotationsButtonsVisible( false ); 
    		clickSelectButton();
    	}
    	
    	if ( ( editMode & EditMode.DATA ) == EditMode.DATA ) {
    		setCommonButtonsVisible( true );    		
    		setCartographicDisplayButtonsVisible( true );    		
    	} else {
    		setCartographicDisplayButtonsVisible( false ); 
    		clickSelectButton();
    	}    	
	}

	private JToolBar.Separator getJSeparatorBaseMap() {
		if ( jSeparatorBaseMap == null ) {
			jSeparatorBaseMap =new JToolBar.Separator();
			jSeparatorBaseMap.setVisible( false );
		}
		
		return jSeparatorBaseMap;
	}
	
	private JToolBar.Separator getJSeparatorCommon() {
		if ( jSeparatorCommon == null ) {
			jSeparatorCommon =new JToolBar.Separator();
			jSeparatorCommon.setVisible( false );
		}
		
		return jSeparatorCommon;
	}	
	
	private JToolBar.Separator getJSeparatorDigitizer() {
		if ( jSeparatorDigitizer == null ) {
			jSeparatorDigitizer =new JToolBar.Separator();
			jSeparatorDigitizer.setVisible( false );
		}
		
		return jSeparatorDigitizer;
	}	
	
	private JToolBar.Separator getJSeparatorAnnotations() {
		if ( jSeparatorAnnotations == null ) {
			jSeparatorAnnotations =new JToolBar.Separator();
			jSeparatorAnnotations.setVisible( false );
		}
		
		return jSeparatorAnnotations;
	}		
	
	private JToolBar.Separator getJSeparatorCartographicDisplay() {
		if ( jSeparatorCartographicDisplay == null ) {
			jSeparatorCartographicDisplay =new JToolBar.Separator();
			jSeparatorCartographicDisplay.setVisible( false );
		}
		
		return jSeparatorCartographicDisplay;
	}		
	
	private void setCommonButtonsVisible( boolean visible ) {
		getJSeparatorCommon().setVisible( visible );		
		
		getJButtonSelect().setVisible( visible );
		getJButtonMultiSelect().setVisible( visible );
		getJButtonDelete().setVisible( visible );
		getJButtonUndo().setVisible( visible );
		getJButtonRedo().setVisible( visible );		
	}	
	
	private void setBaseMapButtonsVisible( boolean visible ) {

		getJSeparatorBaseMap().setVisible( visible );
		getJSeparatorDigitizer().setVisible( visible );
		
		getJButtonSelectByPolygonName().setVisible( visible );
		getJButtonPolygon().setVisible( visible );
		getJButtonClosePolygon().setVisible( visible );
		getJButtonUseExistingBoundaries().setVisible( visible );
		getJButtonMergePolygon().setVisible( visible );
		getJButtonSplitPolygon().setVisible( visible );			
		getJButtonInsertPolygonPoint().setVisible( visible );	    		
		getJButtonDeletePolygonPoint().setVisible( visible );	
		getJButtonDisputedBorder().setVisible( visible );
		getJButtonBaseMapLineWidth().setVisible( visible );
		getJButtonDigitizerWithoutDesc().setVisible( visible );
		getJButtonDigitizer().setVisible( visible );		
	}
	
	private void setAnnotationsButtonsVisible( boolean visible ) {
		getJSeparatorAnnotations().setVisible( visible );
		
		getJButtonPalette().setVisible( visible );
		getJButtonFill().setVisible( visible );			
		getJButtonText().setVisible( visible );
		getJButtonLabelList().setVisible( visible );	

		getJButtonImage().setVisible( visible );
		getJButtonBackgroundImage().setVisible( visible );
		getJButtonLine().setVisible( visible );				
		getJButtonRectangle().setVisible( visible );
		getJButtonEllipse().setVisible( visible );
		getJButtonTriangle().setVisible( visible );				
		getJButtonCross().setVisible( visible );
	}
	
	private void setCartographicDisplayButtonsVisible( boolean visible ) {
		getJSeparatorCartographicDisplay().setVisible( visible );		
		
		getJButtonPointEntry().setVisible( visible );	
		getJButtonPointEntryWithoutDesc().setVisible( visible );			
		getJButtonSelectByCDPointDesc().setVisible( visible );
	}
	
	private JToolBar getJToolBar() {
		if ( jToolBar == null ) {
			jToolBar = new JToolBar("Map Toolbar");
			ButtonGroup buttonGroup =new ButtonGroup();

			buttonGroup.add( getJButtonSelect() );
			buttonGroup.add( getJButtonMultiSelect() );	
			buttonGroup.add( getJButtonText() );
			buttonGroup.add( getJButtonZoomIn() );
			buttonGroup.add( getJButtonZoomOut() );
			buttonGroup.add( getJButtonLabelList() );				
			buttonGroup.add( getJButtonLine() );
			buttonGroup.add( getJButtonRectangle() );			
			buttonGroup.add( getJButtonEllipse() );	
			buttonGroup.add( getJButtonCross() );	
			buttonGroup.add( getJButtonTriangle() );
			buttonGroup.add( getJButtonBackgroundImage() );	
			buttonGroup.add( getJButtonImage() );			
			buttonGroup.add( getJButtonPolygon() );
			buttonGroup.add( getJButtonFill() );
			buttonGroup.add( getJButtonInsertPolygonPoint() );			
			buttonGroup.add( getJButtonDeletePolygonPoint() );
			buttonGroup.add( getJButtonUseExistingBoundaries() );	
			buttonGroup.add( getJButtonSplitPolygon() );
			buttonGroup.add( getJButtonDisputedBorder() );
			buttonGroup.add( getJButtonPointEntry() );
			buttonGroup.add( getJButtonPointEntryWithoutDesc() );
			buttonGroup.add( getJButtonDigitizerWithoutDesc() );
			buttonGroup.add( getJButtonDigitizer() );	
			buttonGroup.add( getJButtonUndo() );	
			buttonGroup.add( getJButtonRedo() );			

			jToolBar.add(getJButtonHelp());	
			jToolBar.add(getJButtonZoomIn());	
			jToolBar.add(getJButtonZoomOut());	
			jToolBar.add(getJButtonFitToWindow());

			jToolBar.add( getJSeparatorCommon() );	
			
			jToolBar.add(getJButtonSelect());
			jToolBar.add(getJButtonMultiSelect());
			jToolBar.add(getJButtonSelectByPolygonName());			
			jToolBar.add(getJButtonDelete());	
			jToolBar.add( getJButtonUndo() );
			jToolBar.add( getJButtonRedo() );			
			
			jToolBar.add( getJSeparatorBaseMap() );	
			
			jToolBar.add(getJButtonPolygon());
			jToolBar.add(getJButtonClosePolygon());			
			jToolBar.add(getJButtonUseExistingBoundaries());
			jToolBar.add(getJButtonMergePolygon());
			jToolBar.add(getJButtonSplitPolygon());			
			jToolBar.add(getJButtonInsertPolygonPoint());			
			jToolBar.add(getJButtonDeletePolygonPoint());
			jToolBar.add(getJButtonDisputedBorder());
			jToolBar.add(getJButtonBaseMapLineWidth());
			
			jToolBar.add( getJSeparatorDigitizer() );			
			
			jToolBar.add( getJButtonDigitizer() );					
			jToolBar.add( getJButtonDigitizerWithoutDesc() );		
			
			jToolBar.add( getJSeparatorAnnotations() );			
			
			jToolBar.add(getJButtonPalette());
			jToolBar.add(getJButtonFill());			
			jToolBar.add(getJButtonText());
			jToolBar.add(getJButtonLabelList());	

			jToolBar.add(getJButtonImage());
			jToolBar.add(getJButtonBackgroundImage());
			jToolBar.add(getJButtonLine());				
			jToolBar.add(getJButtonRectangle());
			jToolBar.add(getJButtonEllipse());
			jToolBar.add(getJButtonTriangle());				
			jToolBar.add(getJButtonCross());	
			
			jToolBar.add( getJSeparatorCartographicDisplay() );
			
			jToolBar.add(getJButtonPointEntry());
			jToolBar.add(getJButtonPointEntryWithoutDesc());			
			jToolBar.add(getJButtonSelectByCDPointDesc());
			
			jToolBar.setFocusable( false );
		}
		return jToolBar;
	}
	
	private void loadIcons( AbstractButton jButton, String iconFilePrefix ) {
		jButton.setIcon( miscHelper.getImageIcon("toolbar/" + iconFilePrefix + "_off.gif") );
		jButton.setPressedIcon( miscHelper.getImageIcon("toolbar/" + iconFilePrefix + "_on.gif") );
		jButton.setRolloverIcon( miscHelper.getImageIcon("toolbar/" + iconFilePrefix + "_roll.gif") );
		jButton.setSelectedIcon( miscHelper.getImageIcon("toolbar/" + iconFilePrefix + "_on.gif") );

		jButton.setBorderPainted(false);
		jButton.setContentAreaFilled(false);
		jButton.setFocusPainted(false);
	}
	
	private JToggleButton getJButtonSelect() {
		if (jButtonSelect == null) {
			jButtonSelect = new JToggleButton();
 			
			loadIcons( jButtonSelect, "ic1_select" );

			jButtonSelect.setSelected(true);
			jButtonSelect.setToolTipText("Select");
			jButtonSelect.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) { 
					repaint();
					
					mtk.setAnchor( null );
					mtk.setDrag( null );					
					
				    mil.setSelectOp( jButtonSelect.isSelected() );
				}
			});
		}
		return jButtonSelect;
	}

	private JToggleButton getJButtonLine() {
		if(jButtonLine == null) {
			jButtonLine = new JToggleButton();

			loadIcons( jButtonLine, "ic10_line" );

			jButtonLine.setToolTipText("New line");
			jButtonLine.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
				    mil.setLineOp( jButtonLine.isSelected() );
				}
			});
		}
		return jButtonLine;
	}	
	 
	private JToggleButton getJButtonImage() {
		if (jButtonImage == null) {
			jButtonImage = new JToggleButton();

			loadIcons( jButtonImage, "ic9_bitmap");
			
			jButtonImage.setToolTipText("Image");

			jButtonImage.setVisible(false);
			jButtonImage.addChangeListener(new ChangeListener() { 
				public void stateChanged(ChangeEvent e) {    
				    mil.setImageOp( jButtonImage.isSelected() );				
				}
			});
		}
		return jButtonImage;
	}	
	
	private JButton getJButtonUndo() {
		if(jButtonUndo == null) {
			jButtonUndo = new JButton();
			loadIcons( jButtonUndo, "undo" );

			jButtonUndo.setToolTipText("Undo");
			jButtonUndo.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					try {
						UndoAction undoAction =undoManager.undo();
						if ( undoAction != null ) {
							repaint();
						
							switch( undoAction.getAction() ) {
								case UndoActions.ADD_CD_POINT:
									refreshAfterCDPointUpdate();
									break;
									
								case UndoActions.MERGE_POLYGON:
								case UndoActions.SPLIT_POLYGON:
									apply();
									break;
							}
						}
					} catch (Exception e1) {
                        new MiscUIHelper().displayErrorMessage( thisFrame, e1 );
						e1.printStackTrace();
					}

				}
			});
		}
		return jButtonUndo;
	}
	
	private JButton getJButtonRedo() {
		if(jButtonRedo == null) {
			jButtonRedo = new JButton();
			loadIcons( jButtonRedo, "redo" );

			jButtonRedo.setToolTipText("Redo");
			jButtonRedo.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					try {
						UndoAction redoAction =undoManager.redo();
						if ( redoAction != null ) {
							repaint();
						
							switch( redoAction.getAction() ) {
								case UndoActions.ADD_CD_POINT:
									refreshAfterCDPointUpdate();
									break;
									
								case UndoActions.MERGE_POLYGON:
								case UndoActions.SPLIT_POLYGON:									
									apply();
									break;
							}
						}
					} catch (Exception e1) {
                        new MiscUIHelper().displayErrorMessage( thisFrame, e1 );
						e1.printStackTrace();
					}
					repaint();
				}
			});
		}
		return jButtonRedo;
	}	
	
	private void refreshAfterCDPointUpdate() {
		((AbstractTableModel)jFrameData.getJTable().getModel()).fireTableDataChanged();
		JPanelCDPoint panelCDPoint =jFrameCartographicDisplay.getJPanelCDPoint();
		panelCDPoint.refreshEntryTables();
	}
		
	public JButton getJButtonDelete() {
		if(jButtonDelete == null) {
			jButtonDelete = new JButton();
			loadIcons( jButtonDelete, "ic5_delete" );

			jButtonDelete.setToolTipText("Delete");
			jButtonDelete.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {  
					
					undoManager.push( UndoActions.DELETE, new ArrayList<MapShape>( mtk.getSelectedShapes() ) );
					
					boolean cdPointSymbolDeleted =mtk.deleteSelectedShapes();
					repaint();	
					if ( cdPointSymbolDeleted ) {
						refreshAfterCDPointUpdate();
					}
				}
			});
		}
		return jButtonDelete;
	}

	private JToggleButton getJButtonPolygon() {
		if(jButtonPolygon == null) {
			jButtonPolygon = new JToggleButton();
			jButtonPolygon.setToolTipText("New polygon");
			loadIcons( jButtonPolygon, "ic11_polygone" );

			jButtonPolygon.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {  
				    mil.setPolygonOp( jButtonPolygon.isSelected() );
				}
			}); 
		}
		return jButtonPolygon;
	}
	
	private JToggleButton getJButtonDigitizerWithoutDesc() {
		if( jToggleButtonDigitizerWithoutDesc == null ){
			jToggleButtonDigitizerWithoutDesc =new JToggleButton();
			jToggleButtonDigitizerWithoutDesc.setToolTipText( "Digitizer input" );
			loadIcons( jToggleButtonDigitizerWithoutDesc, "ic_digitizer" );
			
			jToggleButtonDigitizerWithoutDesc.addItemListener(new ItemListener(){
				
				public void itemStateChanged(ItemEvent e) {
					mil.setDigitizerWithoutDescOp( jToggleButtonDigitizerWithoutDesc.isSelected() );
				}
			});
		}
		
		return jToggleButtonDigitizerWithoutDesc;
	}
	
	private JToggleButton getJButtonDigitizer() {
		if( jToggleButtonDigitizer == null ){
			jToggleButtonDigitizer =new JToggleButton();
			jToggleButtonDigitizer.setToolTipText( "Digitizer input with description popup" );
			loadIcons( jToggleButtonDigitizer, "digitabc" );
			
			jToggleButtonDigitizer.addItemListener(new ItemListener(){
				
				public void itemStateChanged(ItemEvent e) {
					mil.setDigitizerOp( jToggleButtonDigitizer.isSelected() );
				}
			});
		}
		
		return jToggleButtonDigitizer;
	}	
	
	private JButton getJButtonClosePolygon() {
		if(jButtonClosePolygon == null) {
			jButtonClosePolygon = new JButton();
			jButtonClosePolygon.setToolTipText("Close current polygon");
			loadIcons( jButtonClosePolygon, "ic12_closepolygone" );

			jButtonClosePolygon.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) { 
					MapShape polygon =mtk.getEditedShape();
					mtk.closePolygon();
					
					if ( polygon != null ) {
						mtk.selectShape( polygon );
						mtk.setEditedShape( polygon );
					}
					
					getJButtonSelect().doClick();
					
					repaint();
				}
			});
		}
		return jButtonClosePolygon;
	}
	
	private JToggleButton getJButtonFill() {
		if(jButtonFill == null) {
			jButtonFill = new JToggleButton();

			loadIcons( jButtonFill, "ic7_color" );
			jButtonFill.setToolTipText("Fill");
			jButtonFill.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {  
				    mil.setFillOp( jButtonFill.isSelected() );
				}
			});
		}
		return jButtonFill;
	}
	
	private JToggleButton getJButtonMultiSelect() {
		if(jButtonMultiSelect == null) {
			jButtonMultiSelect = new JToggleButton();
			
			loadIcons( jButtonMultiSelect, "ic2_selectzone" );
			
			jButtonMultiSelect.setToolTipText("Multi-select");
			jButtonMultiSelect.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {   
				    mil.setMultiSelectOp( jButtonMultiSelect.isSelected() );
				}
			});
		}
		return jButtonMultiSelect;
	}
	
	private JButton getJButtonPalette() {
		if(jButtonPalette == null) {
			jButtonPalette = new JButton();

			loadIcons( jButtonPalette, "ic6_palette" );
			jButtonPalette.setToolTipText("Palette");
			jButtonPalette.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					//mtk.setCurrentColor( JColorChooser.showDialog( null, "Select a color", mtk.getCurrentColor() ) );
					JDialogColors dlg =new JDialogColors( null );
					dlg.setModal( true );
					
					dlg.setBackgroundColor( mtk.getThematicMap().getAnnotations().getBackgroundColor() ); 
					dlg.setBaseMapColor( mtk.getThematicMap().getAnnotations().getBaseMapColor() );
					dlg.setCurrentColor( mtk.getCurrentColor() );
					
					dlg.setVisible( true );
					if ( dlg.okHasBeenClicked() ) {
						mtk.getThematicMap().getAnnotations().setBackgroundColor( dlg.getBackgroundColor() );
						mtk.getThematicMap().getAnnotations().setBaseMapColor( dlg.getBaseMapColor() );						
						mtk.setCurrentColor( dlg.getCurrentColor() );
						
						repaint();
					}
					dlg.dispose();
				}
			});
		}
		return jButtonPalette;
	}
	
	private JToggleButton getJButtonText() {
		if(jButtonText == null) {
			jButtonText = new JToggleButton();
			jButtonText.setToolTipText("New text");
			loadIcons( jButtonText, "ic8_texte" );

			jButtonText.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {   
				    mil.setTextOp( jButtonText.isSelected() );
				}
			});
		}
		return jButtonText;
	}
	
	public JPanel getJPanel() {
		if (jPanel == null) {
			jPanel = new BaseMapJPanel();
			jPanel.setAutoscrolls(true);
			jPanel.setBackground(Color.white);
			jPanel.setFocusable( true );
			jPanel.addKeyListener( kl );
		}
		return jPanel;
	}
	
	private JLabel getJLabelZoomInfo() {
		if ( jLabelZoomInfo == null ) {
			jLabelZoomInfo = new JLabel();
		}
		
		return jLabelZoomInfo;
	}
	
	private JToolBar getJToolBarZoom() {
		if (jToolBarZoom == null) {
			
			jLabelZoom = new JLabel();
			jToolBarZoom = new JToolBar();
			jLabelZoom.setText("Zoom ");
			jToolBarZoom.setName("Map Zoom");
			jToolBarZoom.add(jLabelZoom);
			jToolBarZoom.add(getJLabelZoomInfo());

			jToolBarZoom.addSeparator();

			jToolBarZoom.add(getJButtonAddMargins());
			jToolBarZoom.add(getJButtonGeographicBox());
			
			jToolBarZoom.addSeparator();			
			
			jToolBarZoom.add(getJCheckBoxMap());
			jToolBarZoom.add(getJCheckBoxCD());
			jToolBarZoom.add(getJCheckBoxAnnotations());
			jToolBarZoom.add(getJLabelCoords());
			
			jToolBarZoom.add( Box.createHorizontalGlue() );
			
			jToolBarZoom.setFocusable( false );
						
		}
		return jToolBarZoom;
	}
	
	private JLabel getJLabelCoords() {
		if ( jLabelCoords == null ) {
			jLabelCoords =new JLabel();
		}
		
		return jLabelCoords;
	}
	
	public void resetZoom() {
		mtk.setZoomFactor( MappingToolKitScalingHelper.DEFAULT_ZOOM_FACTOR );
		displayZoom();
	}
	
	public void displayZoom() {
		jLabelZoomInfo.setText( mtk.getZoomFactor() + "%" );
	}
	  
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane( getJPanel() );
			jScrollPane.setPreferredSize( new Dimension(300, 200) );
			jScrollPane.setFocusable( true );
			jScrollPane.addKeyListener( kl );
		}
		return jScrollPane;
	}
	 
	private JPanel getJMainPanel() {
		if (jMainPanel == null) {
			jMainPanel = new JPanel();
			jMainPanel.setLayout( new BorderLayout() );
			jMainPanel.add(getJToolBar(), BorderLayout.NORTH );
			jMainPanel.add(getJScrollPane(), BorderLayout.CENTER );
			jMainPanel.add(getJToolBarZoom(), BorderLayout.SOUTH);
			jMainPanel.setFocusable( true );
			jMainPanel.addKeyListener( kl );
		}
		return jMainPanel;
	}
	
	public MappingToolKit getMappingToolKit() {
	    return mtk;
	}
	
	public BaseMap getBaseMap() {
	    return baseMap;
	}
	
	public void setBaseMap( BaseMap baseMap ) {
	    this.baseMap =baseMap;
	}
   
	private JButton getJButtonFitToWindow() {
		if (jButtonFitToWindow == null) {
			jButtonFitToWindow = new JButton();
			loadIcons( jButtonFitToWindow, "ic_fittowindow" );
			jButtonFitToWindow.setToolTipText( "Fit to window" );
			jButtonFitToWindow.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					fitToWindow();
				}
			});
		}
		return jButtonFitToWindow;
	}
	
	public void fitToWindow() {
	    mtk.fitToWindow();
	    
	    resetZoom();		
	}
	
	private JButton getJButtonGeographicBox() {
		if (jButtonGeographicBox == null) {
			jButtonGeographicBox = new JButton();

			loadIcons( jButtonGeographicBox, "ic18_coordonnees" );
			jButtonGeographicBox.setToolTipText( "Geographic box" );
			jButtonGeographicBox.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					editGeographicBox();
				}
			});
		}
		return jButtonGeographicBox;
	}
	
	public void editGeographicBox() {
		JDialogGeographicBox geoBox =new JDialogGeographicBox( JOptionPane.getFrameForComponent( thisFrame ) );
		geoBox.setXMin( mtk.getMinX() );
		geoBox.setXMax( mtk.getMaxX() );
		geoBox.setYMin( mtk.getMinY() );
		geoBox.setYMax( mtk.getMaxY() );
		
		geoBox.setModal( true );
		geoBox.setVisible( true );		
		
		if ( geoBox.dataHasChanged() ) {
			mtk.updateGeographicBox( geoBox.getXMin(), geoBox.getXMax(), geoBox.getYMin(), geoBox.getYMax() );
		    
		    mtk.fitToWindow();
		    
		    resetZoom();					    
		}
		
		geoBox.dispose();		
	}
	
	public void setDefaultGeographicBox() {
		mtk.setDefaultGeographicBox();
	    
	    mtk.fitToWindow();
	    
	    resetZoom();	
	}
	   
	private JButton getJButtonMergePolygon() {
		if (jButtonMergePolygon == null) {
			jButtonMergePolygon = new JButton();
			jButtonMergePolygon.setToolTipText("Merge two selected polygons");
			loadIcons( jButtonMergePolygon, "merge" );
			
			jButtonMergePolygon.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
				    try {
				    	if ( mtk.getSelectedShapes().size() == 2 && mtk.getSelectedShapes().get(0) instanceof PolygonShape 
				    											 && mtk.getSelectedShapes().get(1) instanceof PolygonShape ) { 
				    		
				    		List<MapShape> mapShapes =new ArrayList<MapShape>();
				    		PolygonShape ps1 =(PolygonShape)mtk.getSelectedShapes().get(0);
				    		mapShapes.add( ps1 );
				    		PolygonShape ps2 =(PolygonShape)mtk.getSelectedShapes().get(1);				    		
				    		mapShapes.add( ps2 );
				    		
				    		MapShape mergedPolygon =mtk.mergeSelectedPolygons();				    		
				    		mapShapes.add( mergedPolygon );	
				    		
				    		undoManager.push( UndoActions.MERGE_POLYGON, mapShapes );
				    		
				    		apply();

				    	} else {
				    		String msg ="";
				    		if ( mtk.getSelectedShapes().size() > 2 ) {
				    			msg ="Please select two polygons only";
				    		} else {
				    			msg ="Please select two polygons first";
				    		}
				    		
				            JOptionPane.showMessageDialog( thisFrame, msg, jButtonMergePolygon.getToolTipText(), JOptionPane.INFORMATION_MESSAGE );
				    	}
                    } catch (Exception e1) {
                        e1.printStackTrace();
                        new MiscUIHelper().displayErrorMessage( thisFrame, e1 );
                    }
				}
			});
		}
		return jButtonMergePolygon;
	}
	  
	private JToggleButton getJButtonDeletePolygonPoint() {
		if (jButtonDeletePolygonPoint == null) {
			jButtonDeletePolygonPoint = new JToggleButton();
			jButtonDeletePolygonPoint.setToolTipText("Delete polygon's point");

			loadIcons( jButtonDeletePolygonPoint, "ic15_deletepoint");
			jButtonDeletePolygonPoint.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {  
				    mil.setDeletePolygonPointOp( jButtonDeletePolygonPoint.isSelected() );				
				}
			});
		}
		return jButtonDeletePolygonPoint;
	}
	   
	private JButton getJButtonSelectByPolygonName() {
		if (jButtonSelectByPolygonName == null) {
			jButtonSelectByPolygonName = new JButton();
			jButtonSelectByPolygonName.setToolTipText("Select using polygon name");

			loadIcons( jButtonSelectByPolygonName, "ic3_selectnom" );
			
			jButtonSelectByPolygonName.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {
				    // Build a sorted collection of polygons
				    Map<String, PolygonShape> polygons =mtk.getPolygonsForSelectionByName();
				    
				    // Display the selection dialog
				    JDialogSelectPolygonByName selectDlg =new JDialogSelectPolygonByName( JOptionPane.getFrameForComponent(thisFrame), true, polygons );
				    selectDlg.setVisible( true );	
				    
				    // Select the polygons
				    List<String> selectedPolygons =selectDlg.getSelectedPolygons();
				    if ( selectedPolygons != null ) {
				    	mtk.selectPolygonsSelectedByName( selectedPolygons );
				    }	    
				    
				    selectDlg.dispose();
					
				    repaint();
				}
			});
		}
		return jButtonSelectByPolygonName;
	}
  
	private JToggleButton getJButtonUseExistingBoundaries() {
		if (jButtonUseExistingBoundaries == null) {
			jButtonUseExistingBoundaries = new JToggleButton();
			jButtonUseExistingBoundaries.setToolTipText("Use existing boundaries");

			loadIcons( jButtonUseExistingBoundaries, "ic19_special" );
			
			jButtonUseExistingBoundaries.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {  
				    mil.setUseExistingBoundariesOp( jButtonUseExistingBoundaries.isSelected() );				
				}
			});

		}
		return jButtonUseExistingBoundaries;
	}
	  
	private JToggleButton getJButtonInsertPolygonPoint() {
		if (jButtonInsertPolygonPoint == null) {
			jButtonInsertPolygonPoint = new JToggleButton();
			jButtonInsertPolygonPoint.setToolTipText("Insert polygon's point");

			loadIcons( jButtonInsertPolygonPoint, "ic14_addpoint" );
			jButtonInsertPolygonPoint.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) { 
				    mil.setInsertPolygonPointOp( jButtonInsertPolygonPoint.isSelected() );					
				}
			});
		}
		return jButtonInsertPolygonPoint;
	}
	   
	private JToggleButton getJButtonSplitPolygon() {
		if (jButtonSplitPolygon == null) {
			jButtonSplitPolygon = new JToggleButton();
			jButtonSplitPolygon.setToolTipText("Split polygon");

			loadIcons( jButtonSplitPolygon, "ic16_border" );
			
			jButtonSplitPolygon.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {   
				    mil.setSplitPolygonOp( jButtonSplitPolygon.isSelected() );
				}
			});
		}
		return jButtonSplitPolygon;
	}

	private JCheckBox getJCheckBoxMap() {
		if (jCheckBoxMap == null) {
			jCheckBoxMap = new JCheckBox();
			jCheckBoxMap.setText("Base map");
			jCheckBoxMap.setSelected(true);
			jCheckBoxMap.setOpaque( false );
			jCheckBoxMap.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					mtk.setMapVisible( !mtk.isMapVisible() );
					repaint();
				}
			});
		}
		return jCheckBoxMap;
	}

	private JCheckBox getJCheckBoxCD() {
		if (jCheckBoxCD == null) {
			jCheckBoxCD = new JCheckBox();
			jCheckBoxCD.setText("Cartographic display");
			jCheckBoxCD.setSelected( true );
			jCheckBoxCD.setOpaque( false );
			jCheckBoxCD.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					mtk.setCartographicDisplayVisible( !mtk.isCartographicDisplayVisible() );
					repaint();				
				}
			});
		}
		return jCheckBoxCD;
	}

	private JCheckBox getJCheckBoxAnnotations() {
		if (jCheckBoxAnnotations == null) {
			jCheckBoxAnnotations = new JCheckBox();
			jCheckBoxAnnotations.setText("Annotations");
			jCheckBoxAnnotations.setSelected( true );
			jCheckBoxAnnotations.setOpaque( false );
			jCheckBoxAnnotations.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					mtk.setAnnotationsVisible( !mtk.isAnnotationsVisible() );
					repaint();					
				}
			});
		}
		return jCheckBoxAnnotations;
	}
	
	public void enableWizardMode( boolean enabled ) {
		getJToolBar().setVisible( !enabled );
		getJToolBarZoom().setVisible( !enabled );
		setIconifiable( !enabled );
		setMaximizable( !enabled );
		
	}

	private JToggleButton getJButtonEllipse() {
		if (jButtonEllipse == null) {
			jButtonEllipse = new JToggleButton();
			
			loadIcons( jButtonEllipse, "ic21_ovale" );

			jButtonEllipse.setToolTipText("New ellipse");			
			
			jButtonEllipse.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
				    mil.setEllipseOp( jButtonEllipse.isSelected() );				
				}
			});
		}
		return jButtonEllipse;
	}

	private JToggleButton getJButtonRectangle() {
		if (jButtonRectangle == null) {
			jButtonRectangle = new JToggleButton();
			
			loadIcons( jButtonRectangle, "ic20_rectangle" );

			jButtonRectangle.setToolTipText("New rectangle");			
			
			jButtonRectangle.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
				    mil.setRectangleOp( jButtonRectangle.isSelected() );				
				}
			});			
		}
		return jButtonRectangle;
	}

	private JToggleButton getJButtonCross() {
		if (jButtonCross == null) {
			jButtonCross = new JToggleButton();
			
			loadIcons( jButtonCross, "ic22_croix" );

			jButtonCross.setToolTipText("New cross");			
			
			jButtonCross.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
				    mil.setCrossOp( jButtonCross.isSelected() );				
				}
			});				
		}
		return jButtonCross;
	}

	private JToggleButton getJButtonTriangle() {
		if (jButtonTriangle == null) {
			jButtonTriangle = new JToggleButton();
			
			loadIcons( jButtonTriangle, "ic22_triangle" );

			jButtonTriangle.setToolTipText("New triangle");			
			
			jButtonTriangle.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
				    mil.setTriangleOp( jButtonTriangle.isSelected() );				
				}
			});				
		}
		return jButtonTriangle;
	}

	private JToggleButton getJButtonLabelList() {
		if (jButtonLabelList == null) {
			jButtonLabelList = new JToggleButton();
			jButtonLabelList.setToolTipText("New label list");
			loadIcons( jButtonLabelList, "ic23_creerliste" );

			jButtonLabelList.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {   
				    mil.setLabelListOp( jButtonLabelList.isSelected() );
				}
			});			
		}
		return jButtonLabelList;
	}

	private JButton getJButtonAddMargins() {
		if (jButtonAddMargins == null) {
			jButtonAddMargins = new JButton();
			loadIcons( jButtonAddMargins, "ic_margin" );
			jButtonAddMargins.setToolTipText( "Add margins..." );	
			jButtonAddMargins.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
			    	JDialogAddMargins dlg =new JDialogAddMargins( JOptionPane.getFrameForComponent( thisFrame ) );
			    	dlg.setModal( true );
			    	dlg.setVisible( true );
			    	
			    	if ( dlg.okHasBeenClicked() ) {
			    		mtk.setMinX( mtk.getMinX() - ( ( Math.abs( mtk.getMaxX() - mtk.getMinX() ) * (double)dlg.getLeftMarginPC().intValue() ) / 100 ) );
			    		mtk.setMaxX( mtk.getMaxX() + ( ( Math.abs( mtk.getMaxX() - mtk.getMinX() ) * (double)dlg.getRightMarginPC().intValue() ) / 100 ) );
			    		
			    		// Top of the screen
			    		mtk.setMaxY( mtk.getMaxY() + ( ( Math.abs( mtk.getMaxY() - mtk.getMinY() ) * (double)dlg.getTopMarginPC().intValue() ) / 100 ) );
			    		mtk.setMinY( mtk.getMinY() - ( ( Math.abs( mtk.getMaxY() - mtk.getMinY() ) * (double)dlg.getTopMarginPC().intValue() ) / 100 ) );

			    		mtk.fitToWindow();
					    
					    resetZoom();	    		
			    	}
			    	
			    	dlg.dispose();
				}
			});			
		}
		return jButtonAddMargins;
	}

	private JButton getJButtonHelp() {
		if (jButtonHelp == null) {
			jButtonHelp = new JButton();
			loadIcons( jButtonHelp, "ic_help" );

			jButtonHelp.setToolTipText("Help");
			jButtonHelp.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					miscUIHelper.showHelp();
				}
			});
		}
		return jButtonHelp;
	}
	
	private JButton getJButtonBaseMapLineWidth() {
		if (jButtonBaseMapLineWidth == null) {
			jButtonBaseMapLineWidth = new JButton();
			loadIcons( jButtonBaseMapLineWidth, "ic_linewidth" );

			jButtonBaseMapLineWidth.setToolTipText("Base map line width");
			jButtonBaseMapLineWidth.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    
					JDialogBaseMapLineWidth dlg =new JDialogBaseMapLineWidth( null );
					dlg.setModal( true );
					dlg.setLineWidth( mtk.getThematicMap().getAnnotations().getBaseMapLineWidth() );
					dlg.setVisible( true );
					if ( dlg.okHasBeenClicked() ) {
						if ( mtk.getThematicMap() != null && mtk.getThematicMap().getAnnotations() != null ) {
							mtk.getThematicMap().getAnnotations().setBaseMapLineWidth( dlg.getLineWidth() );
							repaint();
						}
					}
					
					dlg.dispose();
				}
			});
		}
		return jButtonBaseMapLineWidth;
	}	
	
	private JButton getJButtonBackgroundImage() {
		if (jButtonBackgroundImage == null) {
			jButtonBackgroundImage = new JButton();
			loadIcons( jButtonBackgroundImage, "bkgimg" );

			jButtonBackgroundImage.setToolTipText("Background image");
			jButtonBackgroundImage.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent e) {    					
					ThematicMapPropertiesUIHelper uiHelper =new ThematicMapPropertiesUIHelper();
					File file =uiHelper.getBackgroundImageFile(thisFrame);
					
					mtk.getBackgroundImage().loadImageFile( file );
					
					mtk.getBackgroundImage().setFile(null);
					
					mtk.getThematicMap().setBackgroundImageLinkedFileName( null );
					
					if ( file != null ) {
						mtk.initializeGeoBoxUsingBackgroundImage();
					
						fitToWindow();
					}
					
					repaint();
				}
			});
		}
		return jButtonBackgroundImage;
	}	

	private JToggleButton getJButtonDisputedBorder() {
		if (jButtonDisputedBorder == null) {
			jButtonDisputedBorder = new JToggleButton();
			jButtonDisputedBorder.setToolTipText("Disputed border");
			
			loadIcons( jButtonDisputedBorder, "dispborder");
			jButtonDisputedBorder.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {  
				    mil.setDisputedBorderOp( jButtonDisputedBorder.isSelected() );				
				}
			});			
		}
		return jButtonDisputedBorder;
	}

	public boolean isGeoBoxNotInitializedAlreadyWarned() {
		return geoBoxNotInitializedAlreadyWarned;
	}

	public void setGeoBoxNotInitializedAlreadyWarned(boolean geoBoxNotInitializedAlreadyWarned) {
		this.geoBoxNotInitializedAlreadyWarned = geoBoxNotInitializedAlreadyWarned;
	}

	private JToggleButton getJButtonZoomIn() {
		if (jToggleButtonZoomIn == null) {
			jToggleButtonZoomIn = new JToggleButton();
			jToggleButtonZoomIn.setToolTipText("Zoom in");
			loadIcons( jToggleButtonZoomIn, "ic17_zoom_plus" );		
			jToggleButtonZoomIn.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {   
				    mil.setZoomInOp( jToggleButtonZoomIn.isSelected() );				
				}
			});				
		}
		return jToggleButtonZoomIn;
	}	
	
	private JToggleButton getJButtonZoomOut() {
		if (jToggleButtonZoomOut == null) {
			jToggleButtonZoomOut = new JToggleButton();
			jToggleButtonZoomOut.setToolTipText("Zoom out");
			loadIcons( jToggleButtonZoomOut, "ic17_zoom_minus" );		
			jToggleButtonZoomOut.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) { 
				    mil.setZoomOutOp( jToggleButtonZoomOut.isSelected() );				
				}
			});				
		}
		return jToggleButtonZoomOut;
	}	
	
	public void resetUI() {
		resetZoom();
		clickSelectButton();
		getJCheckBoxMap().setSelected( true );
		getJCheckBoxCD().setSelected( true );	
		getJCheckBoxAnnotations().setSelected( true );	
		getJLabelCoords().setText("");
	}
	
	/**
	 * 
	 * @return true if the point entry operation can be turned on
	 */
	private boolean enablePointEntryOp() {
		if ( !((String)jFrameCartographicDisplay.getJComboBoxCartographicDisplay().getSelectedItem())
				.equals( CDTypes.names[ CDTypes.POINT ] ) ) {
            JOptionPane.showMessageDialog(thisFrame,
            		"Please select the Point cartographic display\nbefore point entry...",
    	            "Create Point Entry Structure",
    	            JOptionPane.WARNING_MESSAGE);   						

    		clickSelectButton();
    		return false;
		} 
		
		int xIdx =jFrameCartographicDisplay.getJPanelCDPoint().getJComboBoxXColumn().getSelectedIndex();
		if ( xIdx == -1 ) {
 			if ( !displayPointEntryDialog( "Please select the X column in the Point cartographic display..." ) ) {
	    		clickSelectButton();
	    		return false;
			}
		} 
		
		int yIdx =jFrameCartographicDisplay.getJPanelCDPoint().getJComboBoxYColumn().getSelectedIndex();
		if ( yIdx == -1 ) {
			if ( !displayPointEntryDialog( "Please select the Y column in the Point cartographic display..." ) ) {
	    		clickSelectButton();
	    		return false;
			}
		} 
		
		if ( xIdx == yIdx ) {
			if ( !displayPointEntryDialog( "Please select a different column for X & Y in the Point cartographic display..." ) ) {
	    		clickSelectButton();
	    		return false;
			}			    		
		} 									
		
		mil.setPointEntryXColumn( (String)jFrameCartographicDisplay.getJPanelCDPoint().getJComboBoxXColumn().getSelectedItem() );
		mil.setPointEntryYColumn( (String)jFrameCartographicDisplay.getJPanelCDPoint().getJComboBoxYColumn().getSelectedItem() );	
		
		return true;
	}

	private JToggleButton getJButtonPointEntry() {
		if (jButtonPointEntry == null) {
			jButtonPointEntry = new JToggleButton();
			jButtonPointEntry.setToolTipText("Point entry with description popup");
			loadIcons( jButtonPointEntry, "point_entry_desc" );					

			jButtonPointEntry.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if ( jButtonPointEntry.isSelected() ) {
						if ( enablePointEntryOp() ) {
							mil.setPointEntryOp( jButtonPointEntry.isSelected() );
						}
					} else {
						mil.setPointEntryOp( false );
					}
				}
			});
		}
		return jButtonPointEntry;
	}
	
	private JToggleButton getJButtonPointEntryWithoutDesc() {
		if (jButtonPointEntryWithoutDesc == null) {
			jButtonPointEntryWithoutDesc = new JToggleButton();
			jButtonPointEntryWithoutDesc.setToolTipText("Point entry without description popup");
			loadIcons( jButtonPointEntryWithoutDesc, "point_entry" );					

			jButtonPointEntryWithoutDesc.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if ( jButtonPointEntryWithoutDesc.isSelected() ) {
						if ( enablePointEntryOp() ) {
							mil.setPointEntryWithoutDescOp( jButtonPointEntryWithoutDesc.isSelected() );
						}
					} else {
						mil.setPointEntryWithoutDescOp( false );
					}
				}
			});
		}
		return jButtonPointEntryWithoutDesc;
	}	
	
	private boolean displayPointEntryDialog( String msg ) {
       	int n =JOptionPane.showConfirmDialog( thisFrame,
                msg + "\n\nDo you want TMap to create a dedicated data structure for point cartographic display ?",
                "Point Entry Issue",
                JOptionPane.YES_NO_CANCEL_OPTION);
        	
        if ( n == JOptionPane.YES_OPTION ){
        	newStructureForPointEntry();
        }
        
        return n == JOptionPane.YES_OPTION;
	}
	
	public void newStructureForPointEntry() {
    	new AttrHelper().buildStructureForPointEntry( mtk.getThematicMap() );
    	
    	// To refresh the data window
    	DataTableDataModel dataModel =(DataTableDataModel)jFrameData.getJTable().getModel();
    	dataModel.setAttrs( mtk.getThematicMap().getData() );
    	jFrameData.setThematicMap( mtk.getThematicMap() );
    	
    	// To refresh the cd window
    	jFrameCartographicDisplay.applyPointEntryStructure();
    	
    	try {
			mtk.getThematicMap().setCartographicDisplay( jFrameCartographicDisplay.getCartographicDisplay() );
		} catch (TMapException e) {
			logger.error( e );
		}
	}

	private JButton getJButtonSelectByCDPointDesc() {
		if (jButtonSelectByCDPointDesc == null) {
			jButtonSelectByCDPointDesc = new JButton();
			jButtonSelectByCDPointDesc.setToolTipText("Select using cartographic display point name");

			loadIcons( jButtonSelectByCDPointDesc, "ic3_selectnom" );			
			jButtonSelectByCDPointDesc
					.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							JDialogSelectCDPointByName dlg =new JDialogSelectCDPointByName( JOptionPane.getFrameForComponent( thisFrame )
																						  ,	true
																						  ,	mtk.getThematicMap().getData() );
							dlg.setVisible( true );
							if ( dlg.getSelectedPoints() != null ) {
								mtk.selectCDPointsByDesc( dlg.getSelectedPoints() );
							}
							dlg.dispose();
						}
					});
		}
		return jButtonSelectByCDPointDesc;
	}

}  
